package com.ray.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.ibatis.javassist.compiler.ast.NewExpr;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.mchange.util.AssertException;
import com.ray.bean.CompanyMaterialCountBean;
import com.ray.bean.CompanyMaterialTableBean;
import com.ray.bean.DatatablesViewPageBean;
import com.ray.bean.FeedOrderDetailBean;
import com.ray.bean.FeedingAndReportBean;
import com.ray.bean.OrderInfoDetailBean;
import com.ray.bean.ProcessBean;
import com.ray.bean.PurchaseOrderBean;
import com.ray.bean.PutOutWarehouseBean;
import com.ray.bean.ReportBean;
import com.ray.bean.WarehouseInOutDetailBean;
import com.ray.bean.WorkshopProductionCycleBean;
import com.ray.exception.ServiceException;
import com.ray.mapper.ApprovalMapper;
import com.ray.mapper.BasicDataMapper;
import com.ray.mapper.CompanyMapper;
import com.ray.mapper.CompanyMaterialMapper;
import com.ray.mapper.DingTalkMapper;
import com.ray.mapper.PurchaseOrderMapper;
import com.ray.mapper.ReturnWarehouseToProviderMapper;
import com.ray.mapper.WarehouseMapper;
import com.ray.mapper.WorkshopMapper;
import com.ray.pojo.MyUser;
import com.ray.util.RedirectUrlUtil;
import com.ray.util.RequestUtil;
import com.ray.util.ResponseUtil;
import com.ray.util.StringUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Service
public class ReturnWarehouseToProviderService {
	
	@Autowired
	ReturnWarehouseToProviderMapper returnWarehouseToProviderMapper;
	@Autowired
	CompanyMaterialMapper companyMaterialMapper;
	@Autowired
	DingTalkMapper dingTalkMapper;
	@Autowired
	WarehouseMapper warehouseMapper;
	@Autowired
	PurchaseOrderMapper purchaseOrderMapper;
	@Autowired
	ApprovalMapper approvalMapper;
	@Autowired
	CompanyMapper companyMapper;
	@Autowired
	BasicDataMapper basicDataMapper;
	@Autowired
	WorkshopMapper workshopMapper;
	
	@Autowired
	CompanyMaterialCountService companyMaterialCountService;
	@Autowired
	WarehouseService warehouseService;
	@Autowired
	CompanyMaterialService companyMaterialService;
	@Autowired
	ApprovalService approvalService;
	@Autowired
	WorkshopService workshopService;
	@Autowired
	PutOutServiceNew putOutServiceNew;
	@Autowired
	BasicDataService basicDataService;
	
	
	
	/**
	 * 获取可退回给供应商的订单采购单
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<CompanyMaterialTableBean> getMaterialCanReturnToProviderData(Map<String, Object> map) {
		DatatablesViewPageBean<CompanyMaterialTableBean> dtvpb = new DatatablesViewPageBean<CompanyMaterialTableBean>();
		List<CompanyMaterialTableBean> returnDataList = returnWarehouseToProviderMapper.getMaterialCanReturnToProviderData(map);
		int count = returnWarehouseToProviderMapper.getMaterialCanReturnToProviderCount(map);
		dtvpb.setiTotalDisplayRecords(count);
		dtvpb.setiTotalRecords(count);
		dtvpb.setReturnData(returnDataList);
		return dtvpb;
	}
	
	/**
	 * 退货给供应商
	 * @param map
	 * @return
	 * @throws CloneNotSupportedException 
	 */
	public String AddReturnMaterialToPrivder(Map<String, Object> map) throws CloneNotSupportedException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//首先 减少库存  其次 插入退货单数据
		JSONObject jsonObject = JSONObject.fromObject(map.get("returnMaterialToProvider"));
		Double returnCount=jsonObject.getDouble("count");
		WarehouseInOutDetailBean warehouseInOutDetailBean = companyMaterialMapper.getInWarehourseByIdOne(jsonObject.getString("id"));
		Assert.isTrue(warehouseInOutDetailBean.getIsBalance()!=1,"已结算记录不支持退货");
		Double notApprovalOutCount=returnWarehouseToProviderMapper.getNotApprovalReturnTopProviderCountByOtherId(warehouseInOutDetailBean.getId(),2);
		Assert.isTrue(warehouseInOutDetailBean.getCount()-warehouseInOutDetailBean.getReturnCount()-notApprovalOutCount>=returnCount,"最多还可以退货"+(warehouseInOutDetailBean.getCount()-warehouseInOutDetailBean.getReturnCount()-notApprovalOutCount));
		
		
//		WarehouseInOutDetailBean returnMaterialToProvider = (WarehouseInOutDetailBean) JSONObject.toBean(returnMaterialToProviderObj, WarehouseInOutDetailBean.class);
		map.put("materialCode", warehouseInOutDetailBean.getMaterialCode());
//		//物料信息
//		CompanyMaterialTableBean cmtb=companyMaterialMapper.getCompanyMaterialTableByMaterialCode(map);
		//库存信息
		CompanyMaterialCountBean cmcb = companyMaterialCountService.getCompanyMaterialCountByMaterial(map);
		//校验物料
//		warehouseService.isCheckMateiral(cmtb,"无法退货");
		//校验库存
		Assert.isTrue(cmcb.getCount()>=returnCount,"库存不足");
//		checkReturnProviderCount(returnMaterialToProvider, cmcb, cmtb);
		//校验当前采购单可退数量
//		checkCanReturnProviderByPurchase(returnMaterialToProvider,map);
		//先插入一条申请记录
		String ckId = dingTalkMapper.getApprovalNo("CK");
		WarehouseInOutDetailBean returnMaterialToProvider =(WarehouseInOutDetailBean) warehouseInOutDetailBean.clone();
		returnMaterialToProvider.setOtherId(warehouseInOutDetailBean.getId());
		returnMaterialToProvider.setId(ckId);
		returnMaterialToProvider.setCreateTime(sdf.format(new Date()));
		returnMaterialToProvider.setCreateUser(map.get("loginUserId").toString());
		returnMaterialToProvider.setType(2);//退货给供应商
		returnMaterialToProvider.setSourceType(2);// 0 不同出入库 1发料 2退回供应商
		returnMaterialToProvider.setCount(returnCount);
		returnMaterialToProvider.setInOutMoney(jsonObject.has("inOutMoney")?jsonObject.getDouble("inOutMoney"):0);
		returnMaterialToProvider.setStatus(0);
		returnMaterialToProvider.setApprovalTime(null);
		returnMaterialToProvider.setApprovalUser(null);
		returnMaterialToProvider.setReturnCount(0.0);
		returnMaterialToProvider.setSumMoneyCount(jsonObject.has("sumMoneyCount")?jsonObject.getDouble("sumMoneyCount"):0);
		returnMaterialToProvider.setReturnMoney(0.0);
		returnMaterialToProvider.setInCountPrice(jsonObject.has("inCountPrice")?jsonObject.getDouble("inCountPrice"):0);
		List<WarehouseInOutDetailBean> inOutList = new ArrayList<WarehouseInOutDetailBean>();
		inOutList.add(returnMaterialToProvider);
		warehouseService.checkTakingIsNotApproval(inOutList,map.get("loginCompany").toString());
		companyMaterialMapper.insertInOutRecode(inOutList);
		inOutList.clear();
		//是否是过账审核
		String msg="";
		boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
		if(isAduit) {
			Map<String,Object> aduitMap=warehouseService.setAduitMap(map);
			aduitMap.put("id", returnMaterialToProvider.getId());
			this.updateReturnToProviderData(aduitMap,1);
		}else {
			msg= companyMaterialService.sendWechatMessage("退货单待审核", 2, "一条退货单待审核", sdf.format(new Date()), map, RedirectUrlUtil.GET_RETURN_TO_PROVIDER, 3);
		}
		return msg;
	}

	//减少库存
	private void updateMaterialCount(WarehouseInOutDetailBean returnMaterialToProvider,Map<String,Object> map) {
		map.put("materialCode", returnMaterialToProvider.getMaterialCode());
		CompanyMaterialCountBean companyMaterialCount = companyMaterialCountService.getCompanyMaterialCountByMaterial(map);
		CompanyMaterialTableBean cmtb=companyMaterialMapper.getCompanyMaterialTableByMaterialCode(map);
		//如果单位相同.那么就是物料单位退货
		if(returnMaterialToProvider.getInOutUnit().equals(cmtb.getUnit())) {
			returnMaterialToProvider.setIsProductionUnit(1);
		}else {
		//生产单位退货	
			returnMaterialToProvider.setIsProductionUnit(2);
		}
		//校验库存
		WarehouseInOutDetailBean copeBean = new WarehouseInOutDetailBean();
		copeBean.setCount(0.0);
		copeBean.setSumMoneyCount(0.0);
		copeBean.setInOutUnit(returnMaterialToProvider.getInOutUnit());
		warehouseService.checkMaterialCount(companyMaterialCount, cmtb, copeBean);
		//减库存
		CompanyMaterialCountBean cmcb = warehouseService.subMaterialCount(companyMaterialCount, returnMaterialToProvider, map, returnMaterialToProvider.getIsProductionUnit());
		companyMaterialCountService.updateCompanyMaterialCountOnCountByMaterialCodeAndWarehouseType(cmcb);
	}
	
	/**
	 * 校验可退回数量
	 */
	public void checkReturnProviderCount(WarehouseInOutDetailBean rmtp,CompanyMaterialCountBean cmcb,CompanyMaterialTableBean cmtb) {
		Map<String,String> paramMap = new HashMap<String,String>();
		paramMap.put("loginCompany", cmcb.getCompany());
		BigDecimal bigCount = new BigDecimal(rmtp.getCount().toString());
		//生产单位
		if(rmtp.getIsProductionUnit()==1) {
			//生产单位的校验 : 仓库数量 - 投料单未出库的块料数 - 当前退货数量
			//投料单还未出库的块料数
			double notOutProductCount = returnWarehouseToProviderMapper.getCanProductToProviderCount(paramMap);
			//退回给供应商还未审核的数量
			double notApprovalCount = returnWarehouseToProviderMapper.getNotApprovalToProviderCount(paramMap);
			BigDecimal bigNotOutProductCount = new BigDecimal("0.0"); 
			BigDecimal bigNotApprovalCount = new BigDecimal("0.0"); 
			BigDecimal bigMaterialCount = new BigDecimal(cmcb.getProductionUnitCount().toString());
			if(notOutProductCount>0) {
				bigNotOutProductCount = new BigDecimal(notOutProductCount+"");
			}
			if(notApprovalCount>0) {
				bigNotApprovalCount = new BigDecimal(notApprovalCount+"");
			}
			Assert.isTrue(bigMaterialCount.subtract(bigNotOutProductCount).subtract(bigNotApprovalCount).subtract(bigCount).doubleValue()>=0, "生产单位库存数不足");
		}else {
		//物料单位
			CompanyMaterialCountBean mapCount  = warehouseMapper.getWarehouseOutByNotStatus(cmcb);
			BigDecimal bigMaterialCount = new BigDecimal("0.0");
			BigDecimal bigMaterialNoStatusCount = new BigDecimal("0.0");
			if(cmcb.getCount()!=null) {
				bigMaterialCount = new BigDecimal(cmcb.getCount().toString());
			}
			if(mapCount.getCount() !=null) {
				bigMaterialNoStatusCount = new BigDecimal(mapCount.getCount().toString());
			}
			Assert.isTrue(bigMaterialCount.subtract(bigMaterialNoStatusCount).subtract(bigCount).doubleValue()>=0, "物料单位库存数不足");
		}
	}
	
	/**
	 * 获取已经生成的退货单
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<WarehouseInOutDetailBean> getReturnToProviderData(Map<String, Object> map) {
		DatatablesViewPageBean<WarehouseInOutDetailBean> dtvpb = new DatatablesViewPageBean<WarehouseInOutDetailBean>();
		List<WarehouseInOutDetailBean> dataList = warehouseMapper.getWarehouseInOutDetailData(map);
		int count = warehouseMapper.getWarehouseInOutDetailCount(map);
		//判断用户是否有权限审核
		//判断审核权限
		Map<String, Object> approvalParam = new HashMap<String,Object>();
		approvalParam.put("type","10"); 
		approvalParam.put("loginUserId", map.get("loginUserId"));
		approvalParam.put("loginCompany", map.get("loginCompany"));
		List<String> userIds = approvalService.getApprovalIdByLoginId(approvalParam);
		for(String userId:userIds) {
			for(WarehouseInOutDetailBean wiodb:dataList) {
				if(userId.equals(wiodb.getCreateUserId())) {
					wiodb.setIsApperval(1);
				}
			}
		}
		dtvpb.setiTotalDisplayRecords(count);
		dtvpb.setiTotalRecords(count);
		dtvpb.setReturnData(dataList);
		return dtvpb;
	}
	
	//校验采购单累计可退数量
	private void checkCanReturnProviderByPurchase(WarehouseInOutDetailBean returnMaterialToProvider,
			Map<String, Object> map) {
		// 可退数量 = 原入库数量 - 已退数量  + 已回数量 > 现申请数量
		Map<String,String> paramMap = new HashMap<String,String>();
		paramMap.put("loginCompany", map.get("loginCompany").toString());
		paramMap.put("purchaseDetailId",returnMaterialToProvider.getPurcharseOrderId());
		PurchaseOrderBean purchaseOrderBean = purchaseOrderMapper.getPurchaseOrderByPurchaseDetailId(paramMap);
		//原入库数
		BigDecimal bigInCount = new BigDecimal(purchaseOrderBean.getInCount().toString());
		//已退数量(已审核+审核中,物料单位数量)
		Double allReturnMaterialCount =  returnWarehouseToProviderMapper.getReturnMaterialOutCountProvderByPurchase(paramMap);
		BigDecimal bigAllReturnMateiralCount = new BigDecimal(allReturnMaterialCount.toString());
		//已回数量(物料单位)
		Double allReturnMaterialInCount = returnWarehouseToProviderMapper.getReturnMaterialInCountByPurchase(paramMap);
		BigDecimal bigAllReturnMaterialInCount = new BigDecimal(allReturnMaterialInCount.toString());
		//现申请数量
		Double returnOutCount = null;
		//生产单位
		if(returnMaterialToProvider.getIsProductionUnit()==1) {
			returnOutCount = returnMaterialToProvider.getSumMoneyCount();
		}else {
		// 物料单位	
			returnOutCount = returnMaterialToProvider.getCount();
		}
		BigDecimal bigReturnOutCount = new BigDecimal(returnOutCount.toString());
		Assert.isTrue(bigInCount.subtract(bigAllReturnMateiralCount).add(bigAllReturnMaterialInCount).subtract(bigReturnOutCount).doubleValue()>=0, "无法退货 最多还可退"+bigInCount.subtract(bigAllReturnMateiralCount).add(bigAllReturnMaterialInCount).doubleValue());
	}
	
	/**
	 * 审核退货单
	 * @param map
	 * @return
	 */
	public String updateReturnToProviderData(Map<String, Object> map,int status) {
		Assert.notNull(map.get("id"),"退回单id为空");
		WarehouseInOutDetailBean wiodb=companyMaterialMapper.getInWarehourseByIdOne(map.get("id").toString());
		WarehouseInOutDetailBean beforeWiodb=companyMaterialMapper.getInWarehourseByIdOne(wiodb.getOtherId());
		Assert.isTrue(wiodb.getStatus()==0, "该退货单已审核,请勿重复操作");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Map<String, Object> approvalParam = new HashMap<String,Object>();
		approvalParam.put("type","10"); 
		approvalParam.put("loginUserId", map.get("loginUserId"));
		approvalParam.put("loginCompany", map.get("loginCompany"));
		List<String> userIds = approvalService.getApprovalIdByLoginId(approvalParam);
		String createUserId = wiodb.getCreateUser();
		Assert.isTrue(userIds.contains(createUserId), "暂无权限审核该退货单");
		wiodb.setStatus(status);
		wiodb.setApprovalReason("退货单审核");
		wiodb.setApprovalTime(sdf.format(new Date()));
		wiodb.setApprovalUser(map.get("loginUserId").toString());
		if(status==1) {
			//减少库存
			this.updateMaterialCount(wiodb, map);
			beforeWiodb.setReturnCount(beforeWiodb.getReturnCount()-wiodb.getCount());
			beforeWiodb.setReturnMoney(beforeWiodb.getReturnMoney()-wiodb.getInOutMoney());
			beforeWiodb.setRetuenSumMoneyCount(beforeWiodb.getRetuenSumMoneyCount() - wiodb.getSumMoneyCount());
			int returnRow = warehouseMapper.updateWarehouInReturnCountAndMoney(beforeWiodb);
		}
		//更新状态
		int row = warehouseMapper.updateWarehouInOutOnStatus(wiodb);
		Assert.isTrue(row>0, "操作失败");
		boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
		String approvalMsg="";
		if(!isAduit) {
			approvalMsg = workshopService.sendApprovalStatusMassage(status, wiodb.getCreateUser(), map.get("loginUserName").toString(), "退货单", RedirectUrlUtil.GET_RETURN_TO_PROVIDER);
		}
		return approvalMsg;
	}
	
	/**
	 * 查询可退回入库的数据
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<CompanyMaterialTableBean> getCanInCountByReturnToProviderData(Map<String, Object> map) {
		DatatablesViewPageBean<CompanyMaterialTableBean> dtvpb = new DatatablesViewPageBean<CompanyMaterialTableBean>();
		List<CompanyMaterialTableBean> dataList = returnWarehouseToProviderMapper.getCanInCountByReturnToProviderData(map);
		int count = returnWarehouseToProviderMapper.getCanInCountByReturnToProviderCount(map);
		dtvpb.setiTotalDisplayRecords(count);
		dtvpb.setiTotalRecords(count);
		dtvpb.setReturnData(dataList);
		return dtvpb;
	}
	
	/**
	 * 保存退货单
	 * @param map
	 * @return
	 */
	public String saveInCountByReturnToProviderData(Map<String, Object> map) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Assert.notNull(map.get("warehouseData"), "物料入库信息为空");
		JSONArray jsonArray=JSONArray.fromObject(map.get("warehouseData").toString());
		//前台传过来的物料集合
		List<WarehouseInOutDetailBean> warehouseDataList=(List<WarehouseInOutDetailBean>) JSONArray.toCollection(jsonArray, WarehouseInOutDetailBean.class);
		List<WarehouseInOutDetailBean> inOutList = new ArrayList<WarehouseInOutDetailBean>();
		List<String> ids = new ArrayList<String>();
		Boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
		Map aduitMap=warehouseService.setAduitMap(map);
		for(WarehouseInOutDetailBean wiodb:warehouseDataList) {
			WarehouseInOutDetailBean olDetailBean=companyMaterialMapper.getInWarehourseByIdOne(wiodb.getId());
			Double notApprovalCount=returnWarehouseToProviderMapper.getNotApprovalReturnTopProviderCountByOtherId(wiodb.getId(), 1);
		    Assert.isTrue(olDetailBean.getReturnCount()+wiodb.getCount()+notApprovalCount<=0,"最多可入库"+(-(olDetailBean.getReturnCount()+notApprovalCount)));
			olDetailBean.setOtherId(olDetailBean.getId());
			String rkId = dingTalkMapper.getApprovalNo("RK");
			olDetailBean.setCreateTime(sdf.format(new Date()));
			olDetailBean.setCreateUser(map.get("loginUserId").toString());
			olDetailBean.setSourceType(2);
			olDetailBean.setStatus(0);
			olDetailBean.setId(rkId);
			olDetailBean.setCount(wiodb.getCount());
			olDetailBean.setInOutMoney(wiodb.getInOutMoney());
			olDetailBean.setInCountPrice(wiodb.getInCountPrice());
			olDetailBean.setRemark(wiodb.getRemark());
			olDetailBean.setReturnCount(0.0);
			olDetailBean.setSumMoneyCount(wiodb.getSumMoneyCount());
			olDetailBean.setReturnMoney(0.0);
			inOutList.add(olDetailBean);
			//校验最大入库数
//			checkReturnWarehouseInCount(wiodb);
			//插入入库记录
		    if(inOutList !=null && inOutList.size()>0) {
		    	companyMaterialMapper.insertInOutRecode(inOutList);
		    	if(isAduit) {
					aduitMap.put("id", inOutList.get(0).getId());
					this.updateInCountByReturnToProvderData(aduitMap,1);
				}
		    	inOutList.clear();
		    	ids.add(rkId);
		    } 
		}
		String msg = "";
		if(!isAduit) {
			if(ids.size()>0) {
				String bodyMessage = "退货入库单需审核";
//	    	String queryCondition = "?ids="+ids.toString().substring(1,ids.toString().length()-1).replace(" ","");
				msg = companyMaterialService.sendWechatMessage("退货入库单待审核", 2, ids.size()+bodyMessage, sdf.format(new Date()), map, RedirectUrlUtil.GET_RETURN_TO_PROVIDER, 1);
			}
		}
		return msg;
	}
	
	/**
	 * 查询退回入库单
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<WarehouseInOutDetailBean> getInCountByReturnToProvderData(Map<String, Object> map) {
		DatatablesViewPageBean<WarehouseInOutDetailBean> dtvpb = new DatatablesViewPageBean<WarehouseInOutDetailBean>();
		List<WarehouseInOutDetailBean> dataList = returnWarehouseToProviderMapper.getInCountByReturnToProvderData(map);
		//判断审核权限
		Map<String, Object> approvalParam = new HashMap<String,Object>();
		approvalParam.put("type","6"); 
		approvalParam.put("loginUserId", map.get("loginUserId"));
		approvalParam.put("loginCompany", map.get("loginCompany"));
		List<String> userIds = approvalService.getApprovalIdByLoginId(approvalParam);
		int isAotoApproval = companyMapper.getIsAutoApprovalByCompany(map);
		//判断当前登录人可审核的单子 
		for(WarehouseInOutDetailBean wod:dataList) {
			if(userIds!=null && userIds.size()>0) {
				for(String createUserId:userIds) {
					//制单人是可以被审核的
					if(wod.getCreateUserId().equals(createUserId)) {
						//判断制单人是否为本人
						if(map.get("loginUserId").equals(wod.getCreateUserId())) {
							if(isAotoApproval == 1) {
								wod.setIsApperval(1);
								break; 
							}
						}else {//制单人非审核人本人
							wod.setIsApperval(1);
							break; 
						}
					}
				}
			}
			if(wod.getStatus()==0) {
				approvalParam.put("loginUserId", wod.getCreateUserId());
				List<String> approvalUserList = approvalMapper.getApprovalUserBeanByLoginUserId(approvalParam);
				wod.setAuditableUser(approvalUserList);
			}
		}
		int count = returnWarehouseToProviderMapper.getInCountByReturnToProvderCount(map);
		dtvpb.setiTotalDisplayRecords(count);
		dtvpb.setiTotalRecords(count);
		dtvpb.setReturnData(dataList);
		return dtvpb;
	}
	
	/**
	 * 审核退货入库单
	 * @param map
	 * @param status
	 * @return    
	 */
	public String updateInCountByReturnToProvderData(Map<String, Object> map, int status) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Assert.notNull(map.get("id"), "入库单id为空");
		WarehouseInOutDetailBean wiodb=companyMaterialMapper.getInWarehourseByIdOne(map.get("id").toString());
		WarehouseInOutDetailBean olDetailBean=companyMaterialMapper.getInWarehourseByIdOne(wiodb.getOtherId());
		Assert.isTrue(wiodb.getStatus()==0, "入库单已审核,请勿重复操作");
		Map<String, Object> approvalParam = new HashMap<String,Object>();
		approvalParam.put("type","6"); 
		approvalParam.put("loginUserId", map.get("loginUserId"));
		approvalParam.put("loginCompany", map.get("loginCompany"));
		List<String> userIds = approvalService.getApprovalIdByLoginId(approvalParam);
		Assert.isTrue(userIds !=null && userIds.contains(wiodb.getCreateUser()), "您暂无权限审核此入库单!");
		if(1==status) {//如果是审核通过更新库存
			BigDecimal bigCount = new BigDecimal(wiodb.getCount().toString());
			map.put("warehouseType", 4);
			map.put("materialCode", wiodb.getMaterialCode());
			List<CompanyMaterialCountBean> companyMaterialCountBeans = companyMaterialCountService.getCompanyMaterialCountListByDetail(map);
			if(companyMaterialCountBeans.size()<1) {
				map.put("warehouseType", 5);
				companyMaterialCountBeans = companyMaterialCountService.getCompanyMaterialCountListByDetail(map);
			}
			Assert.isTrue(companyMaterialCountBeans.size()==1, "库存信息为空或多条");
			CompanyMaterialCountBean cmcb = companyMaterialCountBeans.get(0);
			//库存数
			BigDecimal materialCount = new BigDecimal(cmcb.getCount().toString());
			cmcb.setCount(materialCount.add(bigCount).doubleValue());
			companyMaterialCountService.updateCompanyMaterialCountOnCountByMaterialCodeAndWarehouseType(cmcb);
			olDetailBean.setReturnCount(olDetailBean.getReturnCount()+wiodb.getCount());
			olDetailBean.setReturnMoney(olDetailBean.getReturnMoney()+wiodb.getInOutMoney());
			olDetailBean.setRetuenSumMoneyCount(olDetailBean.getRetuenSumMoneyCount()+wiodb.getSumMoneyCount());
			int returnRow=warehouseMapper.updateWarehouInReturnCountAndMoney(olDetailBean);
		}
		wiodb.setApprovalTime(sdf.format(new Date()));
		wiodb.setApprovalReason("退货入库单审核");
		wiodb.setApprovalUser(map.get("loginUserId").toString());
		wiodb.setStatus(status);
		int row = warehouseMapper.updateWarehouInOutOnStatus(wiodb);
		Assert.isTrue(row>0, "审核失败");
		Boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
		String approvalMsg="";
		if(!isAduit) {
			approvalMsg = workshopService.sendApprovalStatusMassage(status, wiodb.getCreateUser(), map.get("loginUserName").toString(), "退货入库单", RedirectUrlUtil.GET_RETURN_TO_PROVIDER);
		}
		return approvalMsg;
	}
	
	//校验退回入库数
	private void checkReturnWarehouseInCount(WarehouseInOutDetailBean wiodb) {
		// 累计退货数量 >= 累计退货入库数  + 当前入库数 
		//获取累计退货数量
		Double allOutCount = returnWarehouseToProviderMapper.getAllReturnToProviderCount(wiodb);
		//累计退货入库数
		Double allInCount = returnWarehouseToProviderMapper.getAllReturnInCount(wiodb);
		//当前入库数
		BigDecimal bigInCount = new BigDecimal(wiodb.getCount().toString());
		BigDecimal bigAllOutCount = new BigDecimal(allOutCount.toString());
		BigDecimal bigAllInCount = new BigDecimal(allInCount.toString());
		Assert.isTrue(bigAllOutCount.subtract(bigAllInCount).subtract(bigInCount).doubleValue()>=0,"入库失败,最大可入库数量"+bigAllOutCount.subtract(bigAllInCount).doubleValue());
	}
	
	/**
	 * 获取车间退回到仓库,并且能出库给车间的
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<WarehouseInOutDetailBean> getWorkShopToWarehouseData(Map<String, Object> map) {
		DatatablesViewPageBean<WarehouseInOutDetailBean> dtvpb = new DatatablesViewPageBean<WarehouseInOutDetailBean>();
		List<WarehouseInOutDetailBean> dataList = returnWarehouseToProviderMapper.getWorkShopToWarehouseData(map);
		int count = returnWarehouseToProviderMapper.getWorkShopToWarehouseCount(map);
		dtvpb.setiTotalDisplayRecords(count);
		dtvpb.setiTotalRecords(count);
		dtvpb.setReturnData(dataList);
		return dtvpb;
	}
	
	/**
	 * 保存车间重新领料的数据
	 * @param map
	 * @return
	 */
	public String saveWorkShopToWarehouseData(Map<String, Object> map) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = sdf.format(new Date());
		JSONArray jsonArray=JSONArray.fromObject(map.get("returnToWorkShopData").toString());
		//前台传过来的物料集合
		List<WarehouseInOutDetailBean> warehouseDataList=(List<WarehouseInOutDetailBean>) JSONArray.toCollection(jsonArray, WarehouseInOutDetailBean.class);
		//用于保存的List
		List<WarehouseInOutDetailBean> inOutList = new ArrayList<WarehouseInOutDetailBean>();
		//用于发微信信息的ids
		List<String> ids = new ArrayList<String>();
		for(WarehouseInOutDetailBean wiodb:warehouseDataList) {
			String ckId = dingTalkMapper.getApprovalNo("CK");
			wiodb.setId(ckId);
			wiodb.setCreateTime(dateString);
			wiodb.setCreateUser(map.get("loginUserId").toString());
			wiodb.setStatus(0);
			wiodb.setCompany(map.get("loginCompany").toString());
			//校验数量
			this.checkReturnToWorkShopCount(wiodb);
			inOutList.add(wiodb);
			//插入入库记录
	    	companyMaterialMapper.insertInOutRecode(inOutList);
	    	inOutList.clear();
	    	ids.add(ckId);
		}
		String msg = "";
		if(ids.size()>0) {
			if(warehouseDataList.get(0).getSource() !=null && warehouseDataList.get(0).getSource().intValue()==2) {
    			map.put("type", "2");
    			map.put("workShopId", "-1");
    			MyUser user = null;
    			if(user==null) {
    				return "无外协审核人员";
    			}
    			map.put("pickingPeople", user.getUserId());
    		}else {
    			map.put("pickingPeople", warehouseDataList.get(0).getPickingPeople()); 
    		}
			String bodyMessage = "条返料单需审核";
	    	String queryCondition = "?ids="+ids.toString().substring(1,ids.toString().length()-1).replace(" ","");
	    	msg = companyMaterialService.sendWechatMessage("返料单待审核", 4, ids.size()+bodyMessage, sdf.format(new Date()), map, RedirectUrlUtil.GET_RETURN_TO_WORKSHOP, 4);
		}
    	return msg;
	}
	
	/**
	 * 查询已经生成的返料单
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean<WarehouseInOutDetailBean> getWorkShopToWorkShopData(Map<String, Object> map) {
		DatatablesViewPageBean<WarehouseInOutDetailBean> dtvpb = new DatatablesViewPageBean<WarehouseInOutDetailBean>();
		List<WarehouseInOutDetailBean> dataList = returnWarehouseToProviderMapper.getWorkShopToWorkShopData(map);
		for(WarehouseInOutDetailBean wiodb:dataList) {
//			if(wiodb.getIsAutoApproval()==0) {
//				if(wiodb.getCreateUserId().equals(map.get("loginUserId"))) {
//					wiodb.setIsApperval(0);
//				}
//			}
		}
		int count = returnWarehouseToProviderMapper.getWorkShopToWorkShopCount(map);
		dtvpb.setiTotalDisplayRecords(count);
		dtvpb.setiTotalRecords(count);
		dtvpb.setReturnData(dataList);
		return dtvpb;
	}
	
	/**
	 * 删除返料单
	 * @param map
	 */
	public void deleteReturnToWorkShop(Map<String, String> map) {
		Assert.notNull(map.get("id"), "id为空");
		WarehouseInOutDetailBean wiodb=companyMaterialMapper.getInWarehourseByIdOne(map.get("id"));
		Assert.isTrue(wiodb!=null, "该出入库单已被删除");
		int row = warehouseMapper.deleteWarehouse(wiodb);
		Assert.isTrue(row>0, "删除出入库失败");
	}
	
	/**
	 * 修改返料单
	 * @param map
	 */
	public void updateReturnToWorkShop(Map<String, String> map) {
		Assert.notNull(map.get("id"), "id为空");
		Assert.notNull(map.get("count"), "申请修改出库数量为空");
		Double updateCount = Double.valueOf(map.get("count"));
		WarehouseInOutDetailBean wiodb=companyMaterialMapper.getInWarehourseByIdOne(map.get("id"));
		Assert.isTrue(wiodb!=null, "该出入库单已被删除");
		Assert.isTrue(wiodb.getStatus()==0, "该出入库单已被审核,修改失败");
		//校验交接数
		if(!"付".equals(wiodb.getInOutUnit())) {
			Assert.notNull(map.get("selfOutFuCount"), "申请修改交接入库数量为空");
			int selfOutFuCount = Integer.parseInt(map.get("selfOutFuCount"));
//			checkUpdateSelfOutFuCount(wiodb,selfOutFuCount);
			wiodb.setSelfOutFuCount(selfOutFuCount);
		}
		//校验出库数
		checkUpdateMateiralOutCount(wiodb,updateCount);
		wiodb.setCount(updateCount);
		//修改数量
		warehouseService.updateWarehouseInOutCount(wiodb);
	}
	
//	private void checkUpdateSelfOutFuCount(WarehouseInOutDetailBean wiodb,int selfOutFuCount) {
//		//查询报工交接数
//		ReportBean reportBean = new ReportBean();
//		reportBean.setMachining(wiodb.getMaterialType());
//		reportBean.setRowIndex(wiodb.getRowIndex());
//		reportBean.setOrderId(wiodb.getOrderId());
//		Long feedTotal = workshopMapper.getOrderCount(reportBean);
//		FeedingAndReportBean feedingAndReportBean=workshopService.GetOrderSystemCount(wiodb.getOrderId(), wiodb.getMaterialType(), wiodb.getRowIndex());
//		feedingAndReportBean.setFeddingCount(feedTotal);
//		//校验数量
//		Assert.isTrue(wiodb.getSelfOutFuCount()<=(feedingAndReportBean.getFeddingCount()-feedingAndReportBean.getWorkShopCount()-feedingAndReportBean.getFinishCount()-feedingAndReportBean.getPutOutCount()+wiodb.getSelfOutFuCount()-selfOutFuCount),
//				wiodb.getMaterialType()+"已有:车间:"+feedingAndReportBean.getWorkShopCount()+"、外协:"+feedingAndReportBean.getPutOutCount()+"、成品:"+feedingAndReportBean.getFinishCount()+",最多还可交接入库"+(feedingAndReportBean.getFeddingCount()-feedingAndReportBean.getWorkShopCount()-feedingAndReportBean.getFinishCount()-feedingAndReportBean.getPutOutCount())+"付");
//	}
	
	private void checkUpdateMateiralOutCount(WarehouseInOutDetailBean wiodb,Double updateCount) {
		// 可修改数 = 总退回到仓库数 - 总返料单数量(审核+未审核) + 当前的数量 - 修改后数量
		//当前的数量
		Double outCount = wiodb.getCount();
		Assert.isTrue(outCount!=null && outCount.doubleValue()>0, "原出库数量异常");
		//总退回到仓库数
		Double allReturnToWarehouseCount = returnWarehouseToProviderMapper.getAllReturnToWarehouseCount(wiodb);
		//总返料单数量
		Double allReturnOutCount = returnWarehouseToProviderMapper.getAllReturnOutCount(wiodb);
		BigDecimal bigOutCount = new BigDecimal(outCount.toString());
		BigDecimal bigAllReturnToWarehouseCount = new BigDecimal(allReturnToWarehouseCount.toString());
		BigDecimal bigAllReturnOutCount = new BigDecimal(allReturnOutCount.toString());
		BigDecimal bigUpdateCount = new BigDecimal(updateCount.toString());
		Assert.isTrue(bigAllReturnToWarehouseCount.subtract(bigAllReturnOutCount).add(bigOutCount).subtract(bigUpdateCount).doubleValue()>=0, "最大可修改数为:"+bigAllReturnToWarehouseCount.subtract(bigAllReturnOutCount).add(bigOutCount).doubleValue());
	}

	public String approvalReturnToWorkShop(Map<String, String> map,int status) throws ServiceException, CloneNotSupportedException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = sdf.format(new Date());
		Assert.notNull(map.get("id"), "id为空");
		WarehouseInOutDetailBean wiodb=companyMaterialMapper.getInWarehourseByIdOne(map.get("id"));
		Assert.isTrue(wiodb!=null, "该出入库单已被删除");
		Assert.isTrue(wiodb.getStatus()==0, "该出入库单已被审核");
		//查询物料
		Map<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("materialCode", wiodb.getMaterialCode());
		paramMap.put("loginCompany", map.get("loginCompany"));
		CompanyMaterialTableBean cmtb=companyMaterialMapper.getCompanyMaterialTableByMaterialCode(paramMap);
		//校验物料
		warehouseService.isCheckMateiral(cmtb, "审核返料单失败");
		if(status==1) {
			//减库存 交接入库
			//校验库存
			warehouseService.checkOutMaterial(cmtb,wiodb);
			paramMap.put("warehouseType", wiodb.getWarehouseType());
			List<CompanyMaterialCountBean> companyMaterialCountList = companyMaterialCountService.getCompanyMaterialCountListByDetail(paramMap);
			CompanyMaterialCountBean companyMaterialCountBean = null;
			if(companyMaterialCountList==null || companyMaterialCountList.size()<1) {
				companyMaterialCountBean = new CompanyMaterialCountBean();
				companyMaterialCountBean.setCount(0.0);
				companyMaterialCountBean.setNoCount(0.0);
				companyMaterialCountBean.setProductionUnitCount(0.0);
				companyMaterialCountBean.setProductionUnitNoCount(0.0);
				companyMaterialCountBean.setCompany(map.get("loginCompany"));
				companyMaterialCountBean.setWarehouseType(wiodb.getWarehouseType());
				companyMaterialCountBean.setMaterialCode(wiodb.getMaterialCode());
				companyMaterialCountService.addCompanyMaterialCount(companyMaterialCountBean);
			}else {
				companyMaterialCountBean = companyMaterialCountList.get(0);
			}
			companyMaterialCountBean = warehouseService.subMaterialCount(companyMaterialCountBean, wiodb, paramMap,1);
			companyMaterialCountService.updateCompanyMaterialCountOnCountByMaterialCodeAndWarehouseType(companyMaterialCountBean);
			//交接入库 或 交接到外协
			paramMap.put("loginUserId", map.get("loginUserId"));
			paramMap.put("dateString",dateString);
			addPutOutSourceByReturnWorkShop(wiodb,paramMap);
		}
		wiodb.setApprovalTime(dateString);
		wiodb.setApprovalReason("返料单审核");
		wiodb.setApprovalUser(map.get("loginUserId").toString());
		wiodb.setStatus(status);
		int row = warehouseMapper.updateWarehouInOutOnStatus(wiodb);
		Assert.isTrue(row>0, "审核失败");
		String approvalMsg = workshopService.sendApprovalStatusMassage(status, wiodb.getCreateUser(), map.get("loginUserName").toString(), "返料单", RedirectUrlUtil.GET_RETURN_TO_WORKSHOP);
		return approvalMsg;
	}
	
	private void addPutOutSourceByReturnWorkShop(WarehouseInOutDetailBean wiodb,Map<String,Object> map) throws ServiceException, CloneNotSupportedException {
		if(wiodb.getSourceType() == 3 && wiodb.getType()==2) {
			OrderInfoDetailBean orderInfoDetail = returnWarehouseToProviderMapper.getOrderDetailByDetail(wiodb.getOrderId(),wiodb.getRowIndex(),wiodb.getMaterialType());
			Assert.notNull(orderInfoDetail, "订单明细为空");
			MyUser myUser = new MyUser();
			myUser.setUserId(map.get("loginUserId").toString());
			myUser.setCompany(map.get("loginCompany").toString());
			if(wiodb.getSource()==2) {
				Assert.notNull(wiodb, "出入库记录为空");
				Assert.notNull(map.get("loginCompany"), "登录公司名为空");
				//物料信息
				PutOutWarehouseBean putOutWarehouseBean = new PutOutWarehouseBean();
				putOutWarehouseBean.setId(wiodb.getId());
				putOutWarehouseBean.setOtherId(wiodb.getId());
				putOutWarehouseBean.setCompany(map.get("loginCompany").toString());
				putOutWarehouseBean.setOrderId(wiodb.getOrderId());
				putOutWarehouseBean.setRowIndex(wiodb.getRowIndex());
				putOutWarehouseBean.setMaterialType(wiodb.getMaterialType());
				putOutWarehouseBean.setApprovalTime(map.get("dateString").toString());
				putOutWarehouseBean.setApprovalUser(map.get("loginUserId").toString());
				putOutWarehouseBean.setCreateUser(wiodb.getCreateUser());
				putOutWarehouseBean.setCreateTime(wiodb.getCreateTime());
				putOutWarehouseBean.setType(0);
				putOutWarehouseBean.setMaterialCode(wiodb.getMaterialCode());
				putOutWarehouseBean.setTypeId(putOutWarehouseBean.getId());
				//如果单位一致,那么就是物料单位出库
				int count = 0;
				if(wiodb.getSelfOutFuCount()==0){
					count =(int)(double) wiodb.getCount();
				}else {
					count = wiodb.getSelfOutFuCount();
				}
				Assert.isTrue(count>0, "发料到外协时,物料单位转换计算后,发料到外协数量不足一付,不可发料");
				putOutWarehouseBean.setCount(count);
				putOutWarehouseBean.setNoCount(0);
				putOutWarehouseBean.setInOutType(1);
				putOutWarehouseBean.setSource(2);
				putOutWarehouseBean.setStatus(1);
				putOutWarehouseBean.setSourceName("原材料仓");
				putOutServiceNew.insertOnePutOutWarehouse(putOutWarehouseBean);
			}else {
				ReportBean reportBean = new ReportBean();
				int count = 0;
				if(wiodb.getSelfOutFuCount()==0){
					count =(int)(double) wiodb.getCount();
				}else {
					count = wiodb.getSelfOutFuCount();
				}
				Assert.isTrue(count>0, "发料到车间时,物料单位转换计算后,发料到车间数量不足一付,不可发料");
				//如果颜色描述为空,则填写色号 
				if(orderInfoDetail.getColorDescription()==null||orderInfoDetail.getColorDescription().trim().equals("") ||orderInfoDetail.getColorDescription().equals("无")) {
					if(orderInfoDetail.getMaterialModel()==null ||orderInfoDetail.getMaterialModel().equals("无") || orderInfoDetail.getMaterialModel().equals("")) {
						throw new ServiceException("无颜色描述与规格不能报工");
					} 
					reportBean.setColor(orderInfoDetail.getMaterialModel());
				}else { 
					reportBean.setColor(orderInfoDetail.getColorDescription());
				} 
				//订单编号
				reportBean.setOrderId(wiodb.getOrderId());
				//行号
				reportBean.setRowIndex(wiodb.getRowIndex());
				//车间id
				reportBean.setWorkShopName(wiodb.getWorkShopId());
				//加工对象(物料类型)
				reportBean.setMachining(wiodb.getMaterialType());
				//状态
				reportBean.setStatus(1);
				//出库Id
				reportBean.setOtherId(wiodb.getId());
				//类型
				reportBean.setOtherType(-1);
				//合格数
				reportBean.setQualified(count);
				//不合格数
				reportBean.setNoQualified(0);
				//物料代码
				reportBean.setMaterialCode(wiodb.getMaterialCode());
				reportBean.setReport("0");
				//审核人
				reportBean.setAuditor(myUser.getUserId());
				//审核时间
				reportBean.setAuditorTime(map.get("dateString").toString());
				//工序
				ProcessBean processBean = basicDataService.getProcessByWorkShopId(reportBean.getWorkShopName());
				//获取车间对象 
				WorkshopProductionCycleBean workshopProductionCycleBean = basicDataMapper.getWorkshopById(reportBean.getWorkShopName());
				//判断是否有设置交接入库工序
				if(processBean==null) {
					throw new ServiceException(workshopProductionCycleBean.getWorkshopName()+"没有设置交接入库工序");
				} 
				//工序id
				reportBean.setProcedur(processBean.getId()); 
				reportBean.setProcedurText(processBean.getProcessName()); 
				//转为json对象
				JSONArray jsonObject = JSONArray.fromObject(reportBean);
				workshopService.insertReport(jsonObject.toString(), wiodb.getCreateUser(), myUser);
			}
		}
	}
	
	/**
	 * 校验返料单出库数量
	 * @param wiodb
	 */
	private void checkReturnToWorkShopCount(WarehouseInOutDetailBean wiodb) {
		Map map=new HashMap();
		map.put("loginCompany", wiodb.getCompany());
		map.put("orderId", wiodb.getOrderId());
		map.put("rowIndex", wiodb.getRowIndex());
		map.put("materialCode", wiodb.getMaterialCode());
		map.put("materialType", wiodb.getMaterialType());
		Double canOutCount = returnWarehouseToProviderMapper.getCanOutToWorkShopCount(map);
		BigDecimal bigCanOutCount = new BigDecimal(canOutCount.toString());
		BigDecimal bigOutCount = new BigDecimal(wiodb.getCount().toString());
		Assert.isTrue(bigCanOutCount.subtract(bigOutCount).doubleValue()>=0,"最多可返料"+bigCanOutCount.doubleValue());
	}

	/**
	 * 删除退货入库单
	 * purchaseIdArray
	 * @param map
	 * @return
	 */
	public String deleteReturnInFrom(Map<String, String> map) {
		StringUtil.checkIsTrue(map, "purchaseIdArray", "未获取到参数");
		String string=map.get("purchaseIdArray");
		JSONArray jsonArray=JSONArray.fromObject(string);
		List<String> idList=jsonArray.subList(0, jsonArray.size());
		Assert.isTrue(idList.size()>0,"未获取到参数");
		int row=returnWarehouseToProviderMapper.updatePurchaseIsDelete(idList);
		return null;
	}
	
	
}
